package com.business.dynamic.controller;


import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.plugins.Page;
import com.business.common.dto.R;
import com.business.common.enums.BusinessExceptionEnum;
import com.business.common.enums.ErrorEnum;
import com.business.common.exception.BusinessException;
import com.business.common.exception.CustomException;
import com.business.common.utils.FileUploadUtil;
import com.business.common.utils.StrKit;
import com.business.common.utils.SystemClock;
import com.business.dynamic.dto.DynamicParams;
import com.business.dynamic.entity.Dynamic;
import com.business.dynamic.entity.vo.DynamicVo;
import com.business.dynamic.service.DynamicService;
import com.business.dynamic.service.impl.UserServiceImpl;
import com.business.dynamic.utils.PageFactory;
import com.business.redis.ExpiresTimeEnum;
import com.business.redis.RedisLock;
import com.business.redis.constant.RedisKeyConstant;
import com.business.redis.utils.RedisUtil;
import com.business.user.annotation.FrequentRequest;
import com.business.user.annotation.TokenPermission;
import com.business.user.entity.UserDetailsDto;
import com.business.user.entity.UserDto;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * 动态表: 后端controller类
 *
 * @author chenjiehong
 * @date 2019-11-29 15:15:38
 * @since 1.0
 */
@RestController
public class DynamicController {


    @Autowired
    private DynamicService dynamicServiceImpl;

    @Autowired
    private UserServiceImpl userService;

    @Autowired
    private FileUploadUtil fileUploadUtil;


    /**
     * 获取新建动态token 控制重复添加
     *
     * @date 2019-11-29 15:15:38
     */
    @PostMapping("/getAddToken")
    @ResponseBody
    @TokenPermission
    @FrequentRequest(5)//控制频繁操作 一分钟内可以操作5次
    public R getAddToken(UserDto userDto) {
        String key = String.format(RedisKeyConstant.DYNAMIC_ADD_TOKEN, userDto.getId());
        long addToken = SystemClock.now();
        //一个小时内有效
        RedisUtil.setValue(key, addToken, ExpiresTimeEnum.LEVEL_1.getExpiresTime());
        return R.success(addToken);
    }


    /**
     * 新增动态表
     *
     * @param params
     * @date 2019-11-29 15:15:38
     */
    @PostMapping("/add")
    @ResponseBody
    @TokenPermission
    @FrequentRequest(5)//控制频繁操作 一分钟内可以操作5次
    public R add(@RequestBody JSONObject params, UserDto userDto) {
        Long addToken = params.getLong("addToken");
        if (addToken == null) {
            throw new CustomException(ErrorEnum.PARAMS_LOSE, "addToken");
        }
        //判断是否重复提交
        String addTokenKey = String.format(RedisKeyConstant.DYNAMIC_ADD_TOKEN, userDto.getId());
        RedisLock redisLock = new RedisLock(addTokenKey);
        try {
            redisLock.lock();
            Long redisAddToken = (Long) RedisUtil.getValue(addTokenKey);
            if (redisAddToken == null || !redisAddToken.equals(addToken)) {
                return R.error(BusinessExceptionEnum.DYNAMIC_ADD_TOKEN_ERROR);
            }
            //更新token时间
            RedisUtil.expire(addTokenKey, ExpiresTimeEnum.LEVEL_1.getExpiresTime());

            DynamicVo dynamicVo = params.toJavaObject(DynamicVo.class);
            if (dynamicVo.getType() == null) {
                throw new CustomException(ErrorEnum.PARAMS_LOSE, "type");
            }
            if (StrKit.isBlank(dynamicVo.getTitle())) {
                throw new CustomException(ErrorEnum.PARAMS_LOSE, "title");
            }
            if (dynamicVo.getTitle().length() > 50) {
                throw new BusinessException(BusinessExceptionEnum.DYNAMIC_TITLE_LENGTH_ERROR);
            }
            if (StrKit.isBlank(dynamicVo.getContent())) {
                throw new CustomException(ErrorEnum.PARAMS_LOSE, "content");
            }
            if (StrKit.isBlank(dynamicVo.getParentCategoryCode())) {
                throw new CustomException(ErrorEnum.PARAMS_LOSE, "parentCategoryCode");
            }
            if (StrKit.isBlank(dynamicVo.getParentCategoryName())) {
                throw new CustomException(ErrorEnum.PARAMS_LOSE, "parentCategoryName");
            }
            dynamicVo.setUserId(userDto.getId());
            DynamicVo r = dynamicServiceImpl.add(dynamicVo);
            RedisUtil.delValue(addTokenKey);
            return R.success(r);
        } finally {
            redisLock.unlock();
        }

    }


    /**
     * 查询动态表
     *
     * @param params
     * @date 2019-11-29 15:15:38
     */
    @PostMapping("/query")
    @ResponseBody
    @TokenPermission(required = false)
    public R query(@RequestBody JSONObject params, UserDto user) {
        Integer id = params.getInteger("id");
        if (id == null) {
            throw new CustomException(ErrorEnum.PARAMS_LOSE, "id");
        }
        String queryKey = String.format(RedisKeyConstant.DYNAMIC_QUERY, id);
        DynamicVo dynamicVo = null;
        if (RedisUtil.hasKey(queryKey)) {
            dynamicVo = (DynamicVo) RedisUtil.getObject(queryKey, DynamicVo.class);
            String likeCountKey = String.format(RedisKeyConstant.DYNAMIC_LIKE, dynamicVo.getId());
            if (RedisUtil.hasKey(likeCountKey)) {
                Long likeCount = RedisUtil.getZSetSize(likeCountKey);
                //更新喜欢人数
                dynamicVo.setLikeQuantity(likeCount.intValue());
            }
        } else {
            dynamicVo = dynamicServiceImpl.query(id, user.getId());
            RedisUtil.setValue(queryKey, dynamicVo, ExpiresTimeEnum.LEVEL_12.getExpiresTime());

        }
        //更新用户信息
        UserDetailsDto userDetailsDto = userService.getUserName(dynamicVo.getUserId());
        if (userDetailsDto != null) {
            dynamicVo.setUserRealName(userDetailsDto.getRealName());
            dynamicVo.setUserHeadUrl(userDetailsDto.getHeadUrl());
        }

        return R.success(dynamicVo);
    }


    /**
     * 分页用户收藏列表
     *
     * @param params
     * @date 2019-11-29 15:15:38
     */
    @PostMapping("/queryPageByUserCollection")
    @ResponseBody
    @TokenPermission
    public R queryPageByUserCollection(@RequestBody JSONObject params, UserDto userDto) {
        Integer userId = params.getInteger("userId");
        if(userId == null){
            userId = userDto.getId();
        }
        Page<Dynamic> page = new PageFactory<Dynamic>().defaultPage(params);
        return R.success(dynamicServiceImpl.queryPageByUserCollection(page,userId));
    }


    /**
     * 分页查询点赞动态表
     *
     * @param params
     * @date 2019-11-29 15:15:38
     */
    @PostMapping("/queryPageByUserLike")
    @ResponseBody
    @TokenPermission
    public R queryPageByUserLike(@RequestBody JSONObject params, UserDto userDto) {
        Integer userId = params.getInteger("userId");
        if(userId == null){
            userId = userDto.getId();
        }
        Page<Dynamic> page = new PageFactory<Dynamic>().defaultPage(params);
        return R.success(dynamicServiceImpl.queryPageByUserLike(page, userId));
    }

    /**
     * 分页查询推荐动态表
     *
     * @param params
     * @date 2019-11-29 15:15:38
     */
    @PostMapping("/queryPageByUserTag")
    @ResponseBody
    @TokenPermission
    public R queryPageByUserTag(@RequestBody JSONObject params, UserDto userDto) {
        Page<Dynamic> page = new PageFactory<Dynamic>().defaultPage(params);
        return R.success(dynamicServiceImpl.queryPageByUserTag(page, userDto.getId()));
    }

    /**
     * 分页查询关注动态表
     *
     * @param params
     * @date 2019-11-29 15:15:38
     */
    @PostMapping("/queryPageByUser")
    @ResponseBody
    @TokenPermission
    public R queryPageByUser(@RequestBody JSONObject params, UserDto userDto) {
        Integer userId = params.getInteger("userId");
        if(userId == null){
            userId = userDto.getId();
        }
        Page<Dynamic> page = new PageFactory<Dynamic>().defaultPage(params);
        return R.success(dynamicServiceImpl.queryPageByUser(page, userId));
    }


    /**
     * 查询用户发布的动态
     *
     * @param params
     * @date 2019-11-29 15:15:38
     */
    @PostMapping("/queryPageByMyself")
    @ResponseBody
    @TokenPermission
    public R queryPageByMyself(@RequestBody JSONObject params, UserDto userDto) {
        Integer userId = params.getInteger("userId");
        if(userId == null){
            userId = userDto.getId();
        }
        Page<Dynamic> page = new PageFactory<Dynamic>().defaultPage(params);
        return R.success(dynamicServiceImpl.queryPageByMyself(page, userId));
    }
    /**
     * 分页查询动态表
     *
     * @param params
     * @date 2019-11-29 15:15:38
     */
    @PostMapping("/queryPage")
    @ResponseBody
    @TokenPermission(required = false)
    public R queryPage(@RequestBody JSONObject params, UserDto userDto) {
        Page<Dynamic> page = new PageFactory<Dynamic>().defaultPage(params);
        DynamicParams dynamicParams = params.toJavaObject(DynamicParams.class);
        return R.success(dynamicServiceImpl.queryPage(page, dynamicParams, userDto.getId()));
    }


    /**
     * 更新动态状态
     *
     * @param params
     * @date 2019-11-29 15:15:38
     */
    @PostMapping("/updateState")
    @ResponseBody
    @TokenPermission
    @FrequentRequest//控制频繁操作 一分钟内可以操作30次
    public R update(@RequestBody JSONObject params, UserDto userDto) {
        Integer dynamicId = params.getInteger("id");
        Integer state = params.getInteger("state");
        if (dynamicId == null) {
            throw new CustomException(ErrorEnum.PARAMS_LOSE, "id");
        }
        if (state == null) {
            throw new CustomException(ErrorEnum.PARAMS_LOSE, "state");
        }
        Integer r = dynamicServiceImpl.updateState(dynamicId, state, userDto.getId());
        //删除缓存
        String queryKey = String.format(RedisKeyConstant.DYNAMIC_QUERY, dynamicId);
        RedisUtil.delValue(queryKey);
        return R.success(r);
    }

    /**
     * 获取推荐列表
     *
     * @date 2019-11-29 15:15:38
     */
    @PostMapping("/getRecommendList")
    @TokenPermission(required = false)
    public R getRecommendList(UserDto userDto) {
        return R.success(dynamicServiceImpl.getRecommendList(userDto.getId()));

    }


    /**
     * 删除动态表
     *
     * @param params
     * @date 2019-11-29 15:15:38
     */
    @PostMapping("/delete")
    @ResponseBody
    @TokenPermission
    @FrequentRequest//控制频繁操作 一分钟内可以操作30次
    public R delete(@RequestBody JSONObject params, UserDto userDto) {
        Integer id = params.getInteger("id");
        Integer r = dynamicServiceImpl.delete(id, userDto.getId());
        //删除缓存
        Set<String> keys = new HashSet<>();
        String countByTypeKey = String.format(RedisKeyConstant.DYNAMIC_MESSAGE_COUNT_BY_TYPE, userDto.getId());
        String countKey = String.format(RedisKeyConstant.DYNAMIC_MESSAGE_COUNT, userDto.getId());
        String likeKey = String.format(RedisKeyConstant.DYNAMIC_LIKE, id);
        String queryKey = String.format(RedisKeyConstant.DYNAMIC_QUERY, id);
        String attributeListKey = String.format(RedisKeyConstant.DYNAMIC_ATTRIBUTE_LIST, id);
        String imagesListKey = String.format(RedisKeyConstant.DYNAMIC_IMAGES, userDto.getId());

        keys.add(countByTypeKey);
        keys.add(countKey);
        keys.add(likeKey);
        keys.add(queryKey);
        keys.add(attributeListKey);
        keys.add(imagesListKey);
        RedisUtil.delValue(keys);
        return R.success(r);
    }


    /**
     * 上传图片
     *
     * @param fileUpload
     * @date 2020-02-26
     */
    @PostMapping("/uploadImage")
    @TokenPermission
    public R uploadImage(@RequestPart("file") MultipartFile fileUpload, UserDto userDto) throws Exception {
        String filUrl = fileUploadUtil.uploadImage(fileUpload);
        //添加到redis中 保存数据库时要清除redis记录
        String key = String.format(RedisKeyConstant.DYNAMIC_UPLOAD_IMAGES, userDto.getId());
        RedisUtil.addSetValue(key, filUrl);
        return R.success(filUrl);
    }

}